import { useRefValue } from '@gnlab/utils/env-react'
import { useObservable } from '@gnlab/utils/env-react/rx'
import { App, notification, Button } from 'antd'
import dayjs from 'dayjs'
import { OrderedMap } from 'immutable'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import type { QywxNotice, QywxInfo, QywxTransfer, RescanInfo } from '@/services/qywxs'
/**
 * 在企业微信变动时触发回调
 */
export default function useQywxNotify() {
  const { modal, message } = App.useApp()
  const [account] = useStreams(services.auth.account$)
  const accountId = account?.id ?? ''

  // 企业微信因为白名单被禁止登录时触发
  const onBlocked = useCallback(
    (info: QywxInfo) => {
      void message.warning(`企业微信主体未在白名单中，禁止登录（corpId: ${info.corpid}）`)
    },
    [message],
  )

  // 企业微信因切换账号等原因退出时触发
  const onLoggingOut = useCallback(
    (info: QywxInfo) => {
      void message.warning(`企业微信 ${info.friendlyName}（wxid:${info.wxid}） 已退出！`)
    },
    [message],
  )

  // 出现容器端（包括 hook 层）报错时触发
  const onContainerError = useCallback(
    ({ wxid, hostname, title, content }: QywxNotice) => {
      modal.warning({
        title: title || '企业微信提醒',
        content: `${content} （wxid: ${wxid ?? ''}, hostname: ${hostname}）`,
        okText: '确定',
      })
    },
    [modal],
  )

  // 接收到企业微信转交消息时触发（转交出去和转交进来的消息都包括）
  const onTransfered = useCallback(
    ({ fromAccountId, fromName, toName, qywxs }: QywxTransfer) => {
      const isSend = fromAccountId === accountId

      const key = `notify-${Date.now()}`
      notification.info({
        key,
        message: '账号转交提醒',
        description: isSend
          ? `你已转交了${
              qywxs.length > 1
                ? ` ${qywxs[0]!.name} 等 ${qywxs.length} 个企微账号`
                : `企微账号 ${qywxs[0]?.name ?? ''}`
            } 给 ${toName}。接下来由他处理这些账号的客户消息。`
          : `${fromName} 向你转交了${
              qywxs.length > 1
                ? ` ${qywxs[0]!.name} 等 ${qywxs.length} 个企微账号`
                : `企微账号 ${qywxs[0]?.name ?? ''}`
            }。接下来由你处理这些账号的客户消息。`,
        duration: null,
        btn: <Button type="primary" size="small" onClick={() => notification.destroy(key)}>
          我知道了
        </Button>,
      })
    },
    [accountId],
  )

  useObservable(
    services.qywxs.events,
    event => {
      if (event.type === 'blocked') onBlocked(event.info)
      if (event.type === 'loggingOut') onLoggingOut(event.info)
    },
    [onBlocked, onLoggingOut],
  )

  useObservable(
    services.qywxs.notices,
    notice => {
      onContainerError(notice)
    },
    [onContainerError],
  )

  useObservable(
    services.qywxs.transfers.transfered,
    info => {
      onTransfered(info)
    },
    [onTransfered],
  )
}

export interface RescanStatusInfo extends RescanInfo {
  scanned: boolean // 是否已成功扫码登录回来
}

export function useRescanQywxs() {
  // 记录被要求再次扫码的企微
  const [infoMap, setInfoMap] = useState(OrderedMap<string, RescanStatusInfo>())
  const infoMapRef = useRefValue(infoMap)
  useObservable(services.qywxs.rescan$, info => {
    let infos = infoMapRef.current.filter(v => v.wxid !== info.wxid)
    infos = infos.set(info.wxid, { ...info, scanned: false })
    setInfoMap(infos)
  })

  // 发现企微登录回来时更新“再次扫码”状态
  useObservable(services.qywxs.events, event => {
    if (event.type !== 'found') return
    const wxid = event.info.wxid
    let infos = infoMapRef.current
    if (infos.has(wxid)) {
      infos = infos.set(wxid, { ...infos.get(wxid)!, scanned: true })
      setInfoMap(infos)
    }
  })

  // 移除记录
  const remove = useCallback(
    (wxids: string[]) =>
      setInfoMap(qywxs => {
        for (const wxid of wxids) qywxs = qywxs.delete(wxid)
        return qywxs
      }),
    [],
  )

  return {
    infoMap,
    remove,
  }
}
